package com.zkthink.ceres.product.strategy;

import com.zkthink.ceres.order.dto.OrderProductDTO;
import com.zkthink.ceres.order.entity.OrderProduct;
import com.zkthink.ceres.product.dto.ChargeDetailDTO;
import com.zkthink.ceres.product.strategy.ChargeDetailStrategy;

import java.util.List;

/**
 * <p>
 * 首件计算运费方式
 * </p>
 *
 * @author vivi.huang
 * @since 2020/5/13
 */
public class FirstItemChargeDetailStrategy implements ChargeDetailStrategy {

    /**
     * I(总件数),fi(首件数),r1(首件数的费用),si(续件数),r2(续件数的费用)
     * I < fi -> r1 ,
     * I > fi -> r1 + ceil((I - fi) / si) * r2
     *
     * @return
     */
    @Override
    public Long calculate(List<OrderProductDTO> orderProductDTOList, ChargeDetailDTO chargeDetailDTO) {

        // 总购买数量
        Integer total = getTotalBuyNum(orderProductDTOList);

        if (total < chargeDetailDTO.getFirstChargeForUnit()) {
            return chargeDetailDTO.getFirstChargeCost();
        }

        if (total > chargeDetailDTO.getFirstChargeForUnit()) {
            return calculateWithBiggerThanFirstForUnit(chargeDetailDTO, Double.valueOf(total));
        }

        return chargeDetailDTO.getFirstChargeCost();
    }

    private Integer getTotalBuyNum(List<OrderProductDTO> orderProductDTOList) {
        return orderProductDTOList.stream().map(OrderProduct::getBuyNum).reduce(0, (acc, item) ->  acc + item);
    }

    protected Long calculateWithBiggerThanFirstForUnit(ChargeDetailDTO chargeDetailDTO, Double total) {
        return chargeDetailDTO.getFirstChargeCost() + Math
            .round(Math.ceil(
                (total - chargeDetailDTO.getFirstChargeForUnit()) / chargeDetailDTO.getContinueChargeForUnit()))
            * chargeDetailDTO.getContinueChargeCost();
    }

}